#include <stdint.h>

// Return the Latin-1 encoding of a Unicode code point, or U+001A (SUB)
// if no mapping exists.
uint8_t latin2(int32_t cp)
{
    static int16_t valid[512] = {
          0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,
         14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
         28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
         42,  43,  44,  45,   0,  46,  47,  48,  49,  50,  51,  52,  53,  54,
         55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
         69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,
         83,  84,  85,  86,  87,  88,  89,  90,  91,   0,  92,  93,  94,  95,
         96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
        110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
        124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,   0,
        137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
        151, 152, 153, 154, 155, 156, 157, 158, 159, 160,   0,   0,   0, 164,
          0,   0, 167, 168,   0,   0,   0,   0, 173,   0,   0, 176,   0,   0,
          0, 180,   0,   0,   0,   0, 184,   0,   0,   0,   0,   0,   0,   0,
          0, 193, 194,   0, 196,   0,   0, 199,   0, 201,   0, 203,   0, 205,
        206,   0,   0,   0, 711, 211, 212,   0, 214, 215,   0,   0, 218,   0,
        220, 221,   0, 223,   0, 225, 226, 728, 729, 228,   0, 731, 231, 733,
        233,   0, 235,   0, 237, 238,   0,   0,   0,   0, 243, 244,   0, 246,
        247,   0,   0, 250,   0, 252, 253,   0,   0,   0,   0, 258, 259, 260,
        261, 262, 263,   0,   0,   0,   0, 268, 269, 270, 271, 272, 273,   0,
          0,   0,   0,   0,   0,   0, 280, 281, 282, 283,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 313, 314,   0,
          0, 317, 318,   0,   0,   0, 321, 322, 323, 324,   0,   0, 327, 328,
          0,   0,   0,   0,   0,   0,   0, 336, 337,   0,   0, 340, 341,   0,
          0, 344, 345, 346, 347,   0,   0, 350, 351, 352, 353, 354, 355, 356,
        357,   0,   0,   0,   0,   0,   0,   0,   0,   0, 366, 367, 368, 369,
          0,   0,   0,   0,   0,   0,   0, 377, 378, 379, 380, 381, 382
    };
    static uint8_t latin2[] = {
          0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,
         14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
         28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
         42,  43,  44,  45,   0,  46,  47,  48,  49,  50,  51,  52,  53,  54,
         55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
         69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,
         83,  84,  85,  86,  87,  88,  89,  90,  91,   0,  92,  93,  94,  95,
         96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
        110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
        124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,   0,
        137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
        151, 152, 153, 154, 155, 156, 157, 158, 159, 160,   0,   0,   0, 164,
          0,   0, 167, 168,   0,   0,   0,   0, 173,   0,   0, 176,   0,   0,
          0, 180,   0,   0,   0,   0, 184,   0,   0,   0,   0,   0,   0,   0,
          0, 193, 194,   0, 196,   0,   0, 199,   0, 201,   0, 203,   0, 205,
        206,   0,   0,   0, 183, 211, 212,   0, 214, 215,   0,   0, 218,   0,
        220, 221,   0, 223,   0, 225, 226, 162, 255, 228,   0, 178, 231, 189,
        233,   0, 235,   0, 237, 238,   0,   0,   0,   0, 243, 244,   0, 246,
        247,   0,   0, 250,   0, 252, 253,   0,   0,   0,   0, 195, 227, 161,
        177, 198, 230,   0,   0,   0,   0, 200, 232, 207, 239, 208, 240,   0,
          0,   0,   0,   0,   0,   0, 202, 234, 204, 236,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 197, 229,   0,
          0, 165, 181,   0,   0,   0, 163, 179, 209, 241,   0,   0, 210, 242,
          0,   0,   0,   0,   0,   0,   0, 213, 245,   0,   0, 192, 224,   0,
          0, 216, 248, 166, 182,   0,   0, 170, 186, 169, 185, 222, 254, 171,
        187,   0,   0,   0,   0,   0,   0,   0,   0,   0, 217, 249, 219, 251,
          0,   0,   0,   0,   0,   0,   0, 172, 188, 175, 191, 174, 190
    };
    int i = (uint32_t)(cp * 8572569u) >> 23;
    return valid[i]==cp ? latin2[i] : 0x1a;
}


#ifdef TEST
int main(void)
{
    static unsigned charset[] = {
        0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
        0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
        0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017,
        0x018, 0x019, 0x01a, 0x01b, 0x01c, 0x01d, 0x01e, 0x01f,
        0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027,
        0x028, 0x029, 0x02a, 0x02b, 0x02c, 0x02d, 0x02e, 0x02f,
        0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037,
        0x038, 0x039, 0x03a, 0x03b, 0x03c, 0x03d, 0x03e, 0x03f,
        0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047,
        0x048, 0x049, 0x04a, 0x04b, 0x04c, 0x04d, 0x04e, 0x04f,
        0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057,
        0x058, 0x059, 0x05a, 0x05b, 0x05c, 0x05d, 0x05e, 0x05f,
        0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067,
        0x068, 0x069, 0x06a, 0x06b, 0x06c, 0x06d, 0x06e, 0x06f,
        0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077,
        0x078, 0x079, 0x07a, 0x07b, 0x07c, 0x07d, 0x07e, 0x07f,
        0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087,
        0x088, 0x089, 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f,
        0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097,
        0x098, 0x099, 0x09a, 0x09b, 0x09c, 0x09d, 0x09e, 0x09f,
        0x0a0, 0x104, 0x2d8, 0x141, 0x0a4, 0x13d, 0x15a, 0x0a7,
        0x0a8, 0x160, 0x15e, 0x164, 0x179, 0x0ad, 0x17d, 0x17b,
        0x0b0, 0x105, 0x2db, 0x142, 0x0b4, 0x13e, 0x15b, 0x2c7,
        0x0b8, 0x161, 0x15f, 0x165, 0x17a, 0x2dd, 0x17e, 0x17c,
        0x154, 0x0c1, 0x0c2, 0x102, 0x0c4, 0x139, 0x106, 0x0c7,
        0x10c, 0x0c9, 0x118, 0x0cb, 0x11a, 0x0cd, 0x0ce, 0x10e,
        0x110, 0x143, 0x147, 0x0d3, 0x0d4, 0x150, 0x0d6, 0x0d7,
        0x158, 0x16e, 0x0da, 0x170, 0x0dc, 0x0dd, 0x162, 0x0df,
        0x155, 0x0e1, 0x0e2, 0x103, 0x0e4, 0x13a, 0x107, 0x0e7,
        0x10d, 0x0e9, 0x119, 0x0eb, 0x11b, 0x0ed, 0x0ee, 0x10f,
        0x111, 0x144, 0x148, 0x0f3, 0x0f4, 0x151, 0x0f6, 0x0f7,
        0x159, 0x16f, 0x0fa, 0x171, 0x0fc, 0x0fd, 0x163, 0x2d9,
    };
    for (int i = 0; i < 256; i++) {
        #define ASSERT(c) if (!(c)) __builtin_trap()
        ASSERT(latin2(charset[i]) == i);
    }
}
#endif
